﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using Dukou.BizService;
using Dukou.Domain;
using Dukou.Extensions;

namespace Dukou.Web.Mvc.Extensions
{
    /// <summary>
    /// 
    /// </summary>
    public static class HtmlHelperEntension
    {
        static HtmlHelperEntension()
        {
            BizServiceWrapper = new BizServiceWrapper();
        }

        public static BizServiceWrapper BizServiceWrapper { get; set; }

        #region DropDownList

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, Type enumType)
        {
            return DropDownList(htmlHelper, name, enumType, null, null, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, Type enumType, Enum selectedItem)
        {
            return DropDownList(htmlHelper, name, enumType, selectedItem, null, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, Type enumType, Enum selectedItem, string optionLabel)
        {
            return DropDownList(htmlHelper, name, enumType, selectedItem, optionLabel, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, Type enumType, Enum selectedItem, string optionLabel, object htmlAttributes)
        {
            IEnumerable<SelectListItem> selectListItems = SelectListItems(enumType, selectedItem);
            return htmlHelper.DropDownList(name, selectListItems, optionLabel, htmlAttributes);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, Type enumType, Enum selectedItem, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            IEnumerable<SelectListItem> selectListItems = SelectListItems(enumType, selectedItem);
            return htmlHelper.DropDownList(name, selectListItems, optionLabel, htmlAttributes);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string category)
        {
            return DropDownList(htmlHelper, name, category, string.Empty, null, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string category, string selectedItem)
        {
            return DropDownList(htmlHelper, name, category, selectedItem, null, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string category, string selectedItem, string optionLabel)
        {
            return DropDownList(htmlHelper, name, category, selectedItem, optionLabel, null);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string category, string selectedItem, string optionLabel, object htmlAttributes)
        {
            IEnumerable<SelectListItem> selectListItems = SelectListItems(category, selectedItem);
            return htmlHelper.DropDownList(name, selectListItems, optionLabel, htmlAttributes);
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string category, string selectedItem, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            IEnumerable<SelectListItem> selectListItems = SelectListItems(category, selectedItem);
            return htmlHelper.DropDownList(name, selectListItems, optionLabel, htmlAttributes);
        }

        #endregion

        #region Encode
        
        public static string Encode(this HtmlHelper htmlHelper, Enum @enum)
        {
            if (@enum == null)
            {
                return string.Empty;
            }

            return htmlHelper.Encode(@enum.GetDescription());
        }

        public static string Encode(this HtmlHelper htmlHelper, DateTime datetime)
        {
            return htmlHelper.Encode(datetime.ToString("yyyy-MM-dd HH:mm:ss"));
        }

        public static string Encode(this HtmlHelper htmlHelper, DateTime? datetime)
        {
            if (datetime == null)
            {
                return string.Empty;
            }
            return htmlHelper.Encode(datetime.Value.ToString("yyyy-MM-dd HH:mm:ss"));
        }

        public static string EncodeDate(this HtmlHelper htmlHelper, DateTime datetime)
        {
            return htmlHelper.Encode(datetime.ToString("yyyy-MM-dd"));
        }

        public static string EncodeDate(this HtmlHelper htmlHelper, DateTime? datetime)
        {
            if (datetime == null)
            {
                return string.Empty;
            }
            return htmlHelper.Encode(datetime.Value.ToString("yyyy-MM-dd"));
        }

        #endregion

        private static IEnumerable<SelectListItem> SelectListItems(string category, string selectedItem)
        {
            selectedItem = selectedItem ?? string.Empty;
            IList<Enumeration> enumerations = BizServiceWrapper.EnumerationBizService.SelectByCategory(category);
            IEnumerable<SelectListItem> selectListItems = enumerations.Select(x =>
            {
                if (selectedItem == x.Name)
                {
                    return new SelectListItem() { Text = x.Name, Value = x.Id.ToString(), Selected = true };
                }
                else
                {
                    return new SelectListItem() { Text = x.Name, Value = x.Id.ToString() };
                }
            });

            return selectListItems;
        }

        private static IEnumerable<SelectListItem> SelectListItems(Type enumType, Enum selectedItem)
        {
            bool selected = true;
            if (selectedItem == null)
            {
                selected = false;
            }
            IList<SelectListItem> selectListItems = new List<SelectListItem>();
            
            foreach (FieldInfo fieldInfo in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                Enum value = (Enum)fieldInfo.GetValue(null);
                int intValue = Convert.ToInt32(value);

                selectListItems.Add(new SelectListItem()
                {
                    Value = intValue.ToString(),
                    Text = value.GetDescription(),
                    Selected = selected ? (Convert.ToInt32(selectedItem) == intValue) : selected,
                });
            }
            return selectListItems;
        }
    }

    public class BizServiceWrapper
    {
        public IEnumerationBizService EnumerationBizService { get; set; }
    }
}